﻿using System;
using System.Collections.Generic;
using System.Threading;
using System.Collections.Concurrent;

namespace CzfSDK
{
	/// <summary>
	/// 对象池(线程不安全)
	/// </summary>
	public class CzfPool<T>
	{
		Func<T> createFunc;
		int max;
		Queue<T> queue;
		int timeout;
		int currentCount;

		public bool throwException = true;

		/// <summary>
		/// Initializes a new instance of the <see cref="CzfSDK.CzfPool`1"/> class.
		/// </summary>
		/// <param name="createFunc">Create func.</param>
		/// <param name="init">Init.</param>
		/// <param name="max">Max.</param>
		/// <param name="timeout">Timeout.</param>
		protected void Init(Func<T> createFunc, int init, int max, int timeout = 3000)
		{
			LogicTool.AssertNotNull (createFunc);
			LogicTool.Assert (init > 0);
			LogicTool.Assert (timeout > 0);
			LogicTool.Assert (max >= init);

			this.timeout = timeout;
			this.createFunc = createFunc;
			this.max = max;
			this.currentCount = init;
			queue = new Queue<T> (max);
			for (var i = 0; i < init; i++) {
				queue.Enqueue (createFunc ());
			}
		}

		public bool Exec(Action<T> action)
		{
			return Exec (action, this.timeout);
		}
		public bool Exec(Action<T> action, int timeout)
		{
			LogicTool.AssertNotNull (action);
			T t = default(T);
			try {
				if(queue.Count > 0){
					t = queue.Dequeue();
				} else if(currentCount < max){
					t = createFunc();
					currentCount++;
				}else{
					if(throwException)
						throw new Exception("对象池中的对象已经用光");
					return false;
				}
				action(t);
				return true;
			} finally {
				if(!t.Equals(default(T)))
					queue.Enqueue (t);
			}
		}
	}
}

